<template>
  <div class="favorites-page" style="background: url('@/assets/welcom-bg.jpg') no-repeat center center fixed; background-size: cover;">
    <h1 style="color:#eee;">我的自选</h1>

    <div v-if="favoritesListWithState.length > 0" class="favorites-list-container">
      <div class="favorites-list mt-3">
        <div v-for="item in favoritesListWithState" :key="item.item_code" class="favorite-item card mb-3" style="background-color: rgba(36, 39, 47, 0.8); border-color: #555;">
          <div class="card-header" @click="toggleChart(item)" style="cursor: pointer; border-color: #555;">
             <div class="d-flex justify-content-between align-items-center">
              <div style="display: flex; align-items: center;">
                <span class="item-type me-2" style="color:#ccc;">{{ item.item_type === 'fund' ? '基金' : '指数' }}</span>
                <span class="item-name me-2" style="color:#fff;">{{ item.name || item.item_code }}</span>
                <span class="item-code text-primary" style="color:#4fc3f7 !important;">({{ item.item_code }})</span>
                 <span v-if="item.item_type === 'fund'" class="item-category ms-2 text-success" style="color:#fff !important;">{{ item.category }}</span>
              </div>
              <!-- Remove Button - keep in header for easy access -->
              <button class="btn btn-outline-danger btn-sm" @click.stop="removeFavorite(item.item_code, item.item_type)">
                移除
              </button>
            </div>
          </div>

          <!-- Collapsible Chart Area -->
          <div v-show="item.isChartVisible" class="card-body">
            <div class="chart-container" :id="`chart-${item.item_type}-${item.item_code}`" style="width: 100%; height: 400px;"></div>
             <p v-if="item.chartLoading" style="color: #eee; text-align: center;">加载中...</p>
             <p v-if="item.chartError" style="color: red; text-align: center;">加载图表失败</p>
          </div>
        </div>
      </div>

      <!-- Prediction Algorithm Configuration Area (Simplified) -->
      <div class="prediction-config-area card mt-4" style="background-color: rgba(36, 39, 47, 0.8); border-color: #555;">
        <div class="card-header" @click="togglePredictionConfig" style="cursor: pointer; border-color: #555;">
          <h4 class="mb-0" style="color:#fff;">预测算法配置
            <span class="toggle-icon" :class="{ rotated: isPredictionConfigOpen }">&raquo;</span>
          </h4>
        </div>
        <div v-show="isPredictionConfigOpen" class="card-body" style="color:#eee;">
          
          <!-- Preset Algorithm Selection (Remains) -->
          <div class="mb-3">
            <label class="form-label">选择预设算法:</label>
            <select v-model="selectedPresetAlgorithm" class="form-select form-select-sm">
              <option value="MACD_CROSS">MACD 信号线交叉</option>
              <option value="RSI_SIGNALS">RSI 信号</option>
              <!-- Add other preset options here later -->
            </select>
          </div>

          <!-- Apply Algorithm Button (Remains) -->
          <div class="algorithm-management mt-3">
              <button class="btn btn-warning" @click="applyAlgorithm">应用算法</button>
          </div>

        </div>
      </div>

    </div>

    <div v-else>
      <p style="color:#eee;">您的自选列表是空的。</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue';
import axios from 'axios';
import * as echarts from 'echarts';

// favoritesList will now store objects with an added state property
const favoritesListWithState = ref([]);
const chartInstances = {}; // To store ECharts instances
const isPredictionConfigOpen = ref(false);
// Removed predictionRules ref
const selectedPresetAlgorithm = ref('MACD_CROSS'); // Default to MACD_CROSS

// Removed indicatorOptions ref

// Function to fetch user's favorites
const fetchFavorites = async () => {
  const userId = localStorage.getItem('user_id'); // Get user ID from localStorage
  if (!userId) {
    console.error('用户未登录，无法获取自选列表。');
    // TODO: Redirect to login or show a login prompt
    return;
  }

  try {
    const response = await axios.get('/api/v1/favorites/list', {
      params: {
        user_id: userId
      }
    });

    if (response.data.code === 200) {
      // Add state property to each item
      favoritesListWithState.value = response.data.data.map(item => ({ ...item, isChartVisible: false, chartLoading: false, chartError: false }));
      console.log('自选列表加载成功:', favoritesListWithState.value);
      // Charts will be rendered when toggled
    } else {
      console.error('获取自选列表失败:', response.data.message);
      favoritesListWithState.value = [];
    }
  } catch (error) {
    console.error('Error fetching favorites:', error);
    favoritesListWithState.value = [];
  }
};

// Function to toggle chart visibility and fetch/render chart if needed
const toggleChart = async (item) => {
    // Toggle visibility state
    item.isChartVisible = !item.isChartVisible;

    // If chart becomes visible and hasn't been loaded/tried before
    if (item.isChartVisible && !chartInstances[`chart-${item.item_type}-${item.item_code}`] && !item.chartLoading && !item.chartError) {
        item.chartLoading = true; // Set loading state
        item.chartError = false; // Reset error state
        await nextTick(); // Ensure DOM is updated before getting element
        await fetchAndRenderChart(item);
        item.chartLoading = false; // Reset loading state after attempt
    }
};

// Function to fetch chart data and render chart for a single item
const fetchAndRenderChart = async (item, signals = []) => {
    const chartId = `chart-${item.item_type}-${item.item_code}`;
    const chartElement = document.getElementById(chartId);
    if (!chartElement) {
        console.error(`Chart element not found for ${chartId}`);
        item.chartError = true; // Indicate error
        return;
    }

    // Dispose existing chart instance if any
    if (chartInstances[chartId]) {
        chartInstances[chartId].dispose();
        delete chartInstances[chartId]; // Remove from map
    }

     // Clear previous error/loading messages
    chartElement.innerHTML = '';

    const chartInstance = echarts.init(chartElement);
    chartInstances[chartId] = chartInstance;

    let chartOption = null;
    let rawChartData = null; // Variable to store raw data

    try {
        if (item.item_type === 'fund') {
            // Fetch fund chart data
            const response = await axios.get('/api/v1/fund/chart-data', {
                params: {
                    interval: 'daily', // Default to daily
                    fund_type: item.category, // Use category from fetched data
                    board: item.board // Use board from fetched data
                }
            });

            if (response.data.code === 200 && response.data.data) {
                rawChartData = response.data.data; // Store raw data
                console.log('Fund chart data received:', response.data); // 添加日志
                console.log('Fund rawChartData structure:', rawChartData); // 添加日志
                chartOption = buildFundChartOption(rawChartData, signals);
            } else {
                 console.error(`Failed to fetch fund chart data for ${item.item_code}: ${response.data.message}`);
                 item.chartError = true; // Indicate error
            }

        } else if (item.item_type === 'index') {
            // Fetch index chart data
            const response = await axios.get('/api/v1/index/kline', {
                 params: {
                    board: item.board, // Use board from fetched data
                    interval: 'daily' // Default to daily
                 }
            });

             if (response.data.code === 200 && response.data.data) {
                 rawChartData = response.data.data; // Store raw data
                 console.log('Index chart data received:', response.data); // 添加日志
                 console.log('Index rawChartData structure:', rawChartData); // 添加日志
                 chartOption = buildIndexChartOption(rawChartData, signals);
             } else {
                  console.error(`Failed to fetch index chart data for ${item.item_code}: ${response.data.message}`);
                  item.chartError = true; // Indicate error
             }
        }

        if (chartOption && rawChartData) { // Ensure both option and raw data are available
            item.chartData = rawChartData; // Store raw data on item
            chartInstance.setOption(chartOption);
        } else if (!item.chartError) { // Only if no specific error was set above
             chartElement.innerHTML = '<p style="color: #eee; text-align: center;">无法加载图表数据</p>';
        }

    } catch (error) {
        console.error(`Error fetching chart data for ${item.item_code}:`, error);
        item.chartError = true; // Indicate error
         chartElement.innerHTML = '<p style="color: red; text-align: center;">加载图表数据出错</p>'; // Show error message on UI
    } finally {
         item.chartLoading = false; // Always reset loading state
    }
};

// Build ECharts option for Fund Chart
const buildFundChartOption = (data, signals = []) => {
    // This is a simplified version. You may need to adapt the logic
    // from FundDashboard.vue's updateChart function to fully replicate it.

     if (!data || !data.klineData || !data.dates) return null;

     console.log('Building Fund Chart Option with data:', data);
     console.log('Raw signals data:', signals);

     // Create a map for faster signal lookup by date
     // Convert signal dates to match kline date format
     const signalMap = new Map(signals.map(signal => {
         // Convert signal date to Date object
         const signalDate = new Date(signal.date);
         // Format to match kline date format: "Mon, DD MMM YYYY 00:00:00 GMT"
         const formattedDate = signalDate.toUTCString();
         console.log('Converting signal date:', signal.date, 'to:', formattedDate);
         return [formattedDate, signal.type];
     }));
     console.log('Signal Map:', signalMap);
     console.log('First few klineData items:', data.klineData.slice(0, 3));

     const volumes = data.klineData.map((item, idx) => [
        idx, item.vol, item.close > item.open ? 1 : -1
     ]);

     // --- Modify kline data to include itemStyle for signals ---
     const klineWithSignals = data.klineData.map(item => {
         const dateStr = item.trade_date;
         console.log('Processing kline item date:', dateStr, 'Signal type:', signalMap.get(dateStr));
         const signalType = signalMap.get(dateStr);

         const candleData = [
             item.open, item.close, item.low, item.high
         ];

         if (signalType) {
             // Add itemStyle for buy/sell signals
             let signalColor;
             let signalColor0;
             if (signalType === 'buy') {
                 // Use white for buy signals
                 signalColor = '#ffffff'; // White
                 signalColor0 = '#ffffff';
             } else if (signalType === 'sell') {
                 // Use black for sell signals
                 signalColor = '#000000'; // Black
                 signalColor0 = '#000000';
             }
             console.log('Adding signal color for date:', dateStr, 'Color:', signalColor);
             // Return data point as object with itemStyle
             return {
                 value: candleData,
                 itemStyle: {
                     color: signalColor,
                     color0: signalColor0
                 }
             };
         } else {
             // Return data point as simple array if no signal
             return candleData;
         }
     });
     // --- End of modifying kline data ---

     console.log('Modified kline data with signals:', klineWithSignals.slice(0, 3));

     const option = {
        backgroundColor: 'transparent',
        tooltip: { trigger: 'axis' },
        legend: { data: ['K线', '成交量'], textStyle: { color: '#eee' } },
         grid: [
           { left: '10%', right: '8%', top: '10%', height: '65%', bottom: '20%' },
           { left: '10%', right: '8%', top: '80%', height: '12%' }
         ],
         xAxis: [
           { type: 'category', data: data.dates, axisLine: { lineStyle: { color: '#888' } }, axisLabel: { color: '#eee' } },
           { type: 'category', gridIndex: 1, data: data.dates, axisLine: { lineStyle: { color: '#888' } }, axisLabel: { color: '#eee' } }
         ],
         yAxis: [
           { scale: true, splitArea: { show: true }, axisLabel: { color: '#eee' } },
           { scale: true, gridIndex: 1, splitNumber: 2, axisLabel: { color: '#eee' } }
         ],
         dataZoom: [
            { type: 'inside', xAxisIndex: [0, 1], start: 0, end: 100 },
            { show: true, xAxisIndex: [0, 1], type: 'slider', top: '96%', start: 0, end: 100 }
         ],
         series: [
           { name: 'K线', type: 'candlestick', data: klineWithSignals }, // Use modified kline data and rely on itemStyle in data
           { name: '成交量', type: 'bar', xAxisIndex: 1, yAxisIndex: 1, data: volumes, itemStyle: { color: '#888' } } // Add color to volume
         ]
     };

     console.log('Generated Fund Chart Option (partial):', { ...option, graphic: 'see console for full graphic array' }); // Log option, avoid logging huge graphic array

     return option;
};

// Build ECharts option for Index Chart
const buildIndexChartOption = (data, signals = []) => {
    // This is a simplified version. You may need to adapt the logic
    // from IndexDashboard.vue's renderChart function to fully replicate it,
    // especially for handling multiple series if you ever need that here.

     if (!data || !data.kline || !data.dates) return null;

     console.log('Building Index Chart Option with data:', data);
     console.log('Raw signals data:', signals);

     // Create a map for faster signal lookup by date
     // Convert signal dates to match kline date format
     const signalMap = new Map(signals.map(signal => {
         // Convert signal date to Date object
         const signalDate = new Date(signal.date);
         // Format to match kline date format: "Mon, DD MMM YYYY 00:00:00 GMT"
         const formattedDate = signalDate.toUTCString();
         console.log('Converting signal date:', signal.date, 'to:', formattedDate);
         return [formattedDate, signal.type];
     }));
     console.log('Signal Map:', signalMap);
     console.log('First few kline items:', data.kline.slice(0, 3));

     const volumes = data.kline.map((item, idx) => [
        idx, item.vol, item.close > item.open ? 1 : -1
     ]);

     // --- Modify kline data to include itemStyle for signals ---
     const klineWithSignals = data.kline.map(item => {
         const dateStr = item.trade_date;
         console.log('Processing kline item date:', dateStr, 'Signal type:', signalMap.get(dateStr));
         const signalType = signalMap.get(dateStr);

         const candleData = [
             item.open, item.close, item.high, item.low
         ];

         if (signalType) {
             // Add itemStyle for buy/sell signals
             let signalColor;
             let signalColor0;
             if (signalType === 'buy') {
                 // Use white for buy signals
                 signalColor = '#ffffff'; // White
                 signalColor0 = '#ffffff';
             } else if (signalType === 'sell') {
                 // Use black for sell signals
                 signalColor = '#000000'; // Black
                 signalColor0 = '#000000';
             }
             console.log('Adding signal color for date:', dateStr, 'Color:', signalColor);
             // Return data point as object with itemStyle
             return {
                 value: candleData,
                 itemStyle: {
                     color: signalColor,
                     color0: signalColor0
                 }
             };
         } else {
             // Return data point as simple array if no signal
             return candleData;
         }
     });
     // --- End of modifying kline data ---

     console.log('Modified kline data with signals:', klineWithSignals.slice(0, 3));

     const option = {
        backgroundColor: 'transparent',
        tooltip: { trigger: 'axis' },
        legend: { data: ['K线', '成交量'], textStyle: { color: '#eee' } },
         grid: [
           { left: '10%', right: '8%', top: '10%', height: '65%', bottom: '20%' },
           { left: '10%', right: '8%', top: '80%', height: '12%' }
         ],
         xAxis: [
           { type: 'category', data: data.dates, axisLine: { lineStyle: { color: '#888' } }, axisLabel: { color: '#eee' } },
           { type: 'category', gridIndex: 1, data: data.dates, axisLine: { lineStyle: { color: '#888' } }, axisLabel: { color: '#eee' } }
         ],
         yAxis: [
           { scale: true, splitArea: { show: true }, axisLabel: { color: '#eee' } },
           { scale: true, gridIndex: 1, splitNumber: 2, axisLabel: { color: '#eee' } }
         ],
         dataZoom: [
            { type: 'inside', xAxisIndex: [0, 1], start: 0, end: 100 },
            { show: true, xAxisIndex: [0, 1], type: 'slider', top: '96%', start: 0, end: 100 }
         ],
         series: [
           { name: 'K线', type: 'candlestick', data: klineWithSignals }, // Use modified kline data and rely on itemStyle in data
           { name: '成交量', type: 'bar', xAxisIndex: 1, yAxisIndex: 1, data: volumes, itemStyle: { color: '#888' } }
         ]
     };

     console.log('Generated Index Chart Option (partial):', { ...option, graphic: 'see console for full graphic array' }); // Log option, avoid logging huge graphic array

     return option;
};

// Function to remove favorite
const removeFavorite = async (itemCode, itemType) => {
    const userId = localStorage.getItem('user_id'); // Get user ID from localStorage
    if (!userId) {
      console.error('用户未登录，无法移除自选。');
      return;
    }

    try {
        const response = await axios.post('/api/v1/favorites/remove', {
            user_id: userId,
            item_code: itemCode,
            item_type: itemType
        });

        if (response.data.code === 200) {
            alert('移除自选成功！');
            // Refresh the list after removal
            fetchFavorites();
        } else {
            alert('移除自选失败: ' + response.data.message);
        }
    } catch (error) {
        console.error('Error removing favorite:', error);
        alert('移除自选失败，请检查网络或稍后再试。');
    }
};

const togglePredictionConfig = () => {
  isPredictionConfigOpen.value = !isPredictionConfigOpen.value;
};

// Removed addRule, removeRule, addConditionGroup, removeConditionGroup, addCondition, removeCondition functions
// Removed saveAlgorithm, loadAlgorithm functions

const applyAlgorithm = async () => {
  const activeItem = favoritesListWithState.value.find(item => item.isChartVisible);
  
  if (!activeItem) {
    alert('请先展开一个自选项目的图表。');
    return;
  }

  let requestBody = {
    item_code: activeItem.item_code,
    item_type: activeItem.item_type,
    board: activeItem.board,
    // Only send preset_algorithm
    preset_algorithm: selectedPresetAlgorithm.value
  };

  if (!requestBody.preset_algorithm) {
       alert('请选择一个预设算法。');
       return;
  }

  // Indicate loading on the specific item's chart area
  activeItem.chartLoading = true;
  activeItem.chartError = false; // Reset error state

  try {
    console.log('Applying algorithm for:', activeItem.item_code, activeItem.item_type, 'Preset:', requestBody.preset_algorithm);

    const response = await axios.post('/api/v1/prediction/calculate_signals', requestBody);

    if (response.data.code === 200 && response.data.data) {
      alert('算法应用成功！');
      console.log('Received signals:', response.data.data.signals);
      // Render signals on the chart

      // --- NEW: Re-fetch and render chart with signals ---
      await fetchAndRenderChart(activeItem, response.data.data.signals);
      // --- End of NEW Logic ---

    } else {
      console.error('应用算法失败:', response.data.message);
      alert('应用算法失败: ' + (response.data.message || '未知错误'));
      activeItem.chartError = true; // Indicate error
    }

  } catch (error) {
    console.error('应用算法请求失败:', error);
    alert('应用算法请求失败，请检查网络或稍后再试。');
    activeItem.chartError = true; // Indicate error
  } finally {
    activeItem.chartLoading = false; // Reset loading state
  }
};

// Fetch favorites when the component is mounted
onMounted(() => {
  fetchFavorites();
});

// Dispose charts when component is unmounted
// import { onUnmounted } from 'vue'; // Need to import onUnmounted
// onUnmounted(() => {
//     for (const id in chartInstances) {
//         if (chartInstances[id]) {
//             chartInstances[id].dispose();
//         }
//     }
// });

</script>

<style scoped>
.favorites-page {
  padding: 20px;
  min-height: 100vh;
  background: url('@/assets/welcom-bg.jpg') no-repeat center center fixed !important;
  background-size: cover !important;
  color: #ecf0f1; /* Reverted to light text */
}

.favorites-list {
  display: grid;
  gap: 20px; /* Gap between favorite items */
   grid-template-columns: repeat(auto-fill, minmax(600px, 1fr)); /* Responsive grid */
}

.favorite-item {
  border-radius: 8px;
  background-color: rgba(36, 39, 47, 0.8); /* Reverted to dark background */
  color: #ecf0f1; /* Reverted to light text */
  border: 1px solid #555; /* Reverted to dark border */
  display: flex;
  flex-direction: column;
  box-shadow: 0 8px 32px rgba(0,0,0,0.25); /* Reverted shadow */
}

.favorite-item .card-header {
    cursor: pointer;
    padding: 15px 20px; /* Add padding to header */
    border-bottom: 1px solid #555; /* Reverted to dark border */
}

.favorite-item .card-body {
    padding: 20px; /* Add padding inside card body */
}

.item-type {
  font-weight: bold;
}

.item-name {
   font-weight: bold;
   font-size: 1.1rem;
}

.item-code {
  font-family: monospace;
}

.item-category {

}

.chart-container {
  margin-top: 15px; /* Space above the chart */
  height: 400px; /* Increased height */
}

.text-light {
  color: #ecf0f1 !important; /* Reverted to light text */
}

.bg-dark {
    background-color: #181a20 !important; /* Reverted to dark background */
}

.bg-secondary {
     background-color: rgba(60, 63, 81, 0.8) !important; /* Adjusted to match template */
}

.text-primary {
   color: #4fc3f7 !important; /* Reverted to teal */
}

.btn-outline-danger {
    color: #dc3545;
    border-color: #dc3545;
}

.btn-outline-danger:hover {
    background-color: #dc3545;
    color: #fff;
}
</style> 